home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / pump_src / ph_fill.asm < prev    next >
Assembly Source File  |  1995-10-26  |  27KB  |  843 lines

  1. ;══════════════════════════════════════════════════════════════════════
  2. ; Rutina de rellenado Phong por environment mapping
  3. ;══════════════════════════════════════════════════════════════════════
  4.  
  5. .386
  6. COMMENT %                  P1
  7.                           +
  8.                          /  \               (P1,P2,P3) dato
  9.                       P4/-----\P2            P4 se calcula
  10.                        /      /
  11.                       /    /
  12.                      /  /
  13.                     //
  14.                    + P3
  15. %
  16.  
  17. ;ONLY_EVEN=1
  18.  
  19.  
  20. MAX_X = 319
  21. MIN_Y = 0
  22. MAX_Y = 199
  23.  
  24. ; Es arbitrario... pero seguro que despista a el que lo mire :)
  25. TO_THE_RITE = 0EFh
  26. TO_THE_LEFT = 05Ah
  27.  
  28.  
  29.  
  30. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  31.  
  32. _DATA   SEGMENT PARA PUBLIC USE32 'DATA'
  33.  
  34.         EXTRN _frame_buffer_adr:DWORD, _env_map_adr:DWORD
  35.         PUBLIC _ex1, _ey1, _ex2, _ey2, _ex3, _ey3
  36.         PUBLIC _u1, _u2, _u3, _v1, _v2, _v3
  37.         PUBLIC _frame_buffer_scan_width
  38.  
  39. ; ─────────────────────────────────────────────────────────────────────
  40. ; Datos de entrada
  41. ; ─────────────────────────────────────────────────────────────────────
  42. ; Misc
  43. _frame_buffer_scan_width DW 320
  44.  
  45. ; Coordenadas proyectadas de los vértices
  46. x1 LABEL WORD
  47. _ex1     DD ?
  48. y1 LABEL WORD
  49. _ey1     DD ?
  50.  
  51. x2 LABEL WORD
  52. _ex2     DD ?
  53. y2 LABEL WORD
  54. _ey2     DD ?
  55.  
  56. x3 LABEL WORD
  57. _ex3     DD ?
  58. y3 LABEL WORD
  59. _ey3     DD ?
  60.  
  61. ; Angulos esféricos de los tres vértices
  62. u1v1 LABEL DWORD
  63. _u1      DW ?
  64. _v1      DW ?
  65.  
  66. u2v2 LABEL DWORD
  67. _u2      DW ?
  68. _v2      DW ?
  69.  
  70. u3v3 LABEL DWORD
  71. _u3      DW ?
  72. _v3      DW ?
  73.  
  74. ; ─────────────────────────────────────────────────────────────────────
  75. ; Variables de la rutina
  76. ; ─────────────────────────────────────────────────────────────────────
  77. ; Incrementos de y
  78. dy21    DD ?
  79. dy31    DD ?
  80. dy32    DD ?
  81.  
  82. ; Punto P4
  83. x4      DW ?
  84. y4      DW ?
  85. u4      DW ?
  86. v4      DW ?
  87.  
  88. ; Rastering
  89. current_y               DW ?
  90. current_frame_buffer_pointer DD ?
  91. scan_filling_dir        DB ?, ?
  92.  
  93. long_side_u             DW ?
  94. long_side_v             DW ?
  95. long_side_x             DD ?
  96. short_side_x            DD ?
  97.  
  98. long_side_inc_u         DW ?
  99. long_side_inc_v         DW ?
  100. long_side_inc_x         DD ?
  101. short_side_inc_x        DD ?
  102.  
  103. pixel_inc_u             DW ?
  104. pixel_inc_v             DW ?
  105.  
  106. _DATA   ENDS
  107. DGROUP  GROUP _DATA
  108. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  109. _TEXT           SEGMENT PARA PUBLIC USE32 'CODE'
  110.                 ASSUME CS:_TEXT, DS:_DATA
  111.  
  112.                 PUBLIC phong_fill_
  113. phong_fill_     PROC
  114.                 pushad
  115.  
  116.                 ; Clipping sencillo en x
  117.                 mov     ax,[x1]
  118.                 mov     bx,[x2]
  119.                 cmp     ax,bx
  120.                 jge     short L1
  121.                 xchg    ax,bx
  122. L1:             cmp     ax,[x3]
  123.                 jge     short L2
  124.                 mov     ax,[x3]
  125. L2:             cmp     ax,0
  126.                 jge     short L3
  127.                 jmp     near ptr L34
  128. L3:             cmp     bx,[x3]
  129.                 jle     short L4
  130.                 mov     bx,[x3]
  131. L4:             cmp     bx,MAX_X
  132.                 jle     short L5
  133.                 jmp     near ptr L34
  134.  
  135.                 ; Ordenar puntos tal que y1 <= y2 <= y3
  136. L5:             mov     ax,[y1]
  137.                 cmp     ax,[y2]
  138.                 jle     short L6
  139.                 mov     eax,[_ex1]
  140.                 mov     ebx,[_ex2]
  141.                 mov     ecx,[_ey1]
  142.                 mov     edx,[_ey2]
  143.                 mov     [_ex2],eax
  144.                 mov     [_ex1],ebx
  145.                 mov     [_ey2],ecx
  146.                 mov     [_ey1],edx
  147.                 mov     eax,[u2v2]
  148.                 mov     ebx,[u1v1]
  149.                 mov     [u2v2],ebx
  150.                 mov     [u1v1],eax
  151. L6:             mov     eax,[_ey2]
  152.                 cmp     eax,[_ey3]
  153.                 jle     short L7
  154.                 mov     eax,[_ex3]
  155.                 mov     ecx,[_ex2]
  156.                 mov     ebx,[_ey3]
  157.                 mov     edx,[_ey2]
  158.                 mov     [_ex2],eax
  159.                 mov     [_ex3],ecx
  160.                 mov     [_ey3],edx
  161.                 mov     [_ey2],ebx
  162.                 mov     eax,[u3v3]
  163.                 mov     ebx,[u2v2]
  164.                 mov     [u2v2],eax
  165.                 mov     [u3v3],ebx
  166. L7:             mov     eax,[_ey1]
  167.                 cmp     eax,[_ey2]
  168.                 jle     short L8
  169.                 mov     eax,[_ex1]
  170.                 mov     ebx,[_ex2]
  171.                 mov     ecx,[_ey1]
  172.                 mov     edx,[_ey2]
  173.                 mov     [_ex2],eax
  174.                 mov     [_ex1],ebx
  175.                 mov     [_ey2],ecx
  176.                 mov     [_ey1],edx
  177.                 mov     eax,[u2v2]
  178.                 mov     ebx,[u1v1]
  179.                 mov     [u1v1],eax
  180.                 mov     [u2v2],ebx
  181. L8:
  182.                 ; Clipping sencillo en y
  183.                 mov     eax,[_ey1]
  184.                 cmp     eax,MAX_Y
  185.                 jle     short L9
  186.                 jmp     near ptr L34
  187. L9:             mov     eax,[_ey3]
  188.                 cmp     eax,MIN_Y
  189.                 jge     short L10
  190.                 jmp     near ptr L34
  191. L10:
  192.                 ; Cálculo de delta(y)
  193.                 mov     eax,[_ey2]
  194.                 sub     eax,[_ey1]
  195.                 jne     short L11
  196.                 jmp     near ptr L35
  197. L11:            mov     [dy21],eax
  198.                 mov     eax,[_ey3]
  199.                 sub     eax,[_ey1]
  200.                 jne     L12
  201.                 inc     eax
  202. L12:            mov     [dy31],eax
  203.                 mov     eax,[_ey3]
  204.                 sub     eax,[_ey2]
  205.                 mov     [dy32],eax
  206.  
  207. L13:
  208.                 ; Inicializa (u,v) para scannear en las aristas
  209.                 mov     ax,[_u1]
  210.                 mov     [long_side_u],ax
  211.                 mov     ax,[_v1]
  212.                 mov     [long_side_v],ax
  213.  
  214.                 ; Calcula los incrementos de (x,u,v) para rasterizar
  215.                 mov     ax,[_u3]
  216.                 sub     ax,[_u1]
  217.                 movsx   eax,ax
  218.                 mov     edx,eax
  219.                 sar     edx,31
  220.                 idiv    [dy31]
  221.                 mov     [long_side_inc_u],ax
  222.                 mov     ax,[_v3]
  223.                 sub     ax,[_v1]
  224.                 movsx   eax,ax
  225.                 mov     edx,eax
  226.                 sar     edx,31
  227.                 idiv    [dy31]
  228.                 mov     [long_side_inc_v],ax
  229.                 mov     eax,[_ex3]
  230.                 sub     eax,[_ex1]
  231.                 shl     eax,16
  232.                 mov     edx,eax
  233.                 sar     edx,31
  234.                 idiv    [dy31]
  235.                 mov     [long_side_inc_x],eax
  236.                 mov     eax,[_ex2]
  237.                 sub     eax,[_ex1]
  238.                 shl     eax,16
  239.                 mov     edx,eax
  240.                 sar     edx,31
  241.                 idiv    [dy21]
  242.                 mov     [short_side_inc_x],eax
  243.  
  244.                 ; Inicializa (x,y) para el barrido de arriba abajo
  245.                 mov     eax,[_ex1]
  246.                 shl     eax,16
  247.                 mov     [long_side_x],eax
  248.                 mov     [short_side_x],eax
  249.                 mov     ax,[y1]
  250.                 mov     [current_y],ax
  251.  
  252.                 ; Calcula los parámetros (u,v,x) del punto 4
  253.                 mov     ax,[_u3]
  254.                 sub     ax,[_u1]
  255.                 movsx   eax,ax
  256.                 imul    [dy21]
  257.                 idiv    [dy31]
  258.                 add     ax,[_u1]
  259.                 mov     [u4],ax
  260.                 mov     ax,[_v3]
  261.                 sub     ax,[_v1]
  262.                 movsx   eax,ax
  263.                 imul    [dy21]
  264.                 idiv    [dy31]
  265.                 add     ax,[_v1]
  266.                 mov     [v4],ax
  267.                 mov     ax,[x3]
  268.                 sub     ax,[x1]
  269.                 movsx   eax,ax
  270.                 imul    [dy21]
  271.                 idiv    [dy31]
  272.                 add     ax,[x1]
  273.                 mov     [x4],ax
  274.  
  275.                 ; Vemos si el lado largo está a la izquierda o la derecha
  276.                 mov     ax,[x4]
  277.                 cmp     ax,[x2]
  278.                 jl      short L14               ; x4 <  x2
  279.                 je      short L17               ; x4 == x2
  280.                 jmp           L18               ; x4 >  x2
  281.  
  282. ; ─────────────────────────────────────────────────────────────────────
  283. ; En las tres siguientes secciones, mutuamente exclusivas, se calculan
  284. ; la dirección en la que rellenar los scans y los incrementos de (z,w)
  285. ; para pixels avanzado en horizontal
  286. ; ─────────────────────────────────────────────────────────────────────
  287. ;**** El lado largo (P1-P3) está a la derecha
  288. L14:            mov     [scan_filling_dir],TO_THE_RITE
  289.                 movzx   eax,[_u2]
  290.                 movzx   ebx,[u4]
  291.                 sub     eax,ebx
  292.                 cdq
  293.                 movsx   ebx,[x2]
  294.                 movsx   ecx,[x4]
  295.                 sub     ebx,ecx
  296.                 or      ebx,ebx
  297.                 jne     short L15
  298.                 inc     ebx
  299. L15:
  300.                 idiv    ebx
  301.                 mov     [pixel_inc_u],ax
  302.                 movzx   eax,[_v2]
  303.                 movzx   ebx,[v4]
  304.                 sub     eax,ebx
  305.                 cdq
  306.                 movsx   ebx,[x2]
  307.                 movsx   ecx,[x4]
  308.                 sub     ebx,ecx
  309.                 or      ebx,ebx
  310.                 jne     short L16
  311.                 inc     ebx
  312. L16:            idiv    ebx
  313.                 mov     [pixel_inc_v],ax
  314.                 jmp           L21
  315.  
  316. ;**** El lado corto y el largo están montados
  317. L17:            mov     [scan_filling_dir],TO_THE_RITE
  318.                 mov     [pixel_inc_v],1
  319.                 mov     [pixel_inc_u],1
  320.                 jmp     short L21
  321.  
  322. ;**** El lado largo está a la izquierda
  323. L18:            mov     [scan_filling_dir],TO_THE_LEFT
  324.                 movzx   eax,[_u2]
  325.                 movzx   ebx,[u4]
  326.                 sub     eax,ebx
  327.                 cdq
  328.                 movsx   ebx,[x4]
  329.                 movsx   ecx,[x2]
  330.                 sub     ebx,ecx
  331.                 or      ebx,ebx
  332.                 jne     short L19
  333.                 inc     ebx
  334. L19:            idiv    ebx
  335.                 mov     [pixel_inc_u],ax
  336.                 movzx   eax,[_v2]
  337.                 movzx   ebx,[v4]
  338.                 sub     eax,ebx
  339.                 cdq
  340.                 movsx   ebx,[x4]
  341.                 movsx   ecx,[x2]
  342.                 sub     ebx,ecx
  343.                 or      ebx,ebx
  344.                 jne     short L20
  345.                 inc     ebx
  346. L20:            idiv    ebx
  347.                 mov     [pixel_inc_v],ax
  348. ; ─────────────────────────────────────────────────────────────────────
  349. L21:
  350.  
  351.  
  352.                 ; Calcula el puntero al frame_buffer
  353.                 movsx   eax,[current_y]
  354.                 movzx   ebx,[_frame_buffer_scan_width]
  355.                 imul    ebx
  356.                 mov     [current_frame_buffer_pointer],eax
  357.  
  358.                 ; Calcula el número de scans a dibujar
  359.                 mov     cx,[y3]
  360.                 sub     cx,[y1]
  361.                 or      cx,cx
  362.                 jnz     L22
  363.                 inc     cx
  364.  
  365.  
  366. ;══════════════════════════════════════════════════════════════════════
  367. ; Bucle principal, una vez por scan
  368. ;══════════════════════════════════════════════════════════════════════
  369. L22:            push    cx
  370.                 ; Comprueba si hemos llegado al punto de rotura (y = y2)
  371.                 mov     ax,[current_y]
  372.                 cmp     ax,[y2]
  373.                 jne     short L23
  374.                         ; Calcula el nuevo incremento de x por scan
  375.                         mov     eax,[_ex3]
  376.                         sub     eax,[_ex2]
  377.                         shl     eax,10H
  378.                         cdq
  379.                         mov     ebx,[_ey3]
  380.                         sub     ebx,[_ey2]
  381.                         idiv    ebx
  382.                         mov     [short_side_inc_x],eax
  383. L23:
  384.  
  385. IFDEF ONLY_EVEN
  386.                 ; Dibuja solo las pares
  387.                 mov     ax,[current_y]
  388.                 test    ax,1
  389.                 jnz     NEAR PTR L33
  390. ENDIF
  391.                 ; Clipping del scan si está arriba o debajo
  392.                 ; de la zona de corte
  393.                 cmp     [current_y],MIN_Y
  394.                 jl      near ptr L33
  395.                 cmp     [current_y],MAX_Y
  396.                 jg      near ptr L33
  397.  
  398.                 ; Hace que esi apunte al primer pixel del scan (frame_buffer)
  399.                 mov     edi,[current_frame_buffer_pointer]
  400.                 mov     eax,[long_side_x]
  401.                 sar     eax,16
  402.                 add     edi,eax
  403.  
  404.                 ; Si estamos rellenando de derecha a izquierda, goto L28
  405.                 cmp     [scan_filling_dir],TO_THE_LEFT
  406.                 je      near ptr L28
  407.  
  408.                 ; Obtiene los parámetros (u,v) para el primer pixel
  409.                 mov     bp,[long_side_u]
  410.                 mov     si,[long_side_v]
  411.  
  412.                 ; Toma las x entre las que pintar el scan
  413.                 mov     ecx,[short_side_x]
  414.                 sar     ecx,10H
  415.                 mov     ebx,[long_side_x]
  416.                 sar     ebx,10H
  417.  
  418.                 ; Hace clipping del scan, comprobando que esté
  419.                 ; totalmente fuera
  420.                 cmp     bx,MAX_X
  421.                 jg      near ptr L33
  422.                 cmp     cx,0
  423.                 jl      near ptr L33
  424.  
  425.                 ; Clipping del scan por la derecha
  426.                 cmp     cx,MAX_X
  427.                 jle     short L24
  428.                 mov     cx,MAX_X
  429. L24:
  430.                 ; Clipping por la izquierda
  431.                 cmp     bx,0
  432.                 jge     short L26
  433.                         ; Avanzando (u,v) y x por cada pixel
  434.                         xor     edx,edx
  435.                         sub     dx,bx
  436.                         mov     bx,0
  437.                         add     edi,edx
  438. L25:                    add     bp,[pixel_inc_u]
  439.                         add     si,[pixel_inc_v]
  440.                         dec     edx
  441.                         jne     short L25
  442. L26:
  443.                 ; Calcula el número de pixels a rellenar
  444.                 sub     cx,bx
  445.                 cmp     cx,0
  446.                 jge     short L27
  447.                 neg     cx
  448. L27:
  449.                 inc     cx
  450.                 movzx   ecx,cx
  451. COMMENT %
  452.                 ; Clipping del scan si está arriba o debajo
  453.                 ; de la zona de corte
  454.                 cmp     [current_y],MIN_Y
  455.                 jl      near ptr L33
  456.                 cmp     [current_y],MAX_Y
  457.                 jg      near ptr L33
  458. %
  459.                 ; Carga los registros con los valores necesarios
  460.                 ; para el inner loop
  461.                 mov     ebx,esi
  462.                 shl     ebx,16
  463.                 mov     bx,bp
  464.                 mov     dx,[pixel_inc_v]
  465.                 shl     edx,16
  466.                 mov     dx,[pixel_inc_u]
  467.  
  468.                 ; Salta en medio del bucle desenrrollado con todo OK
  469.                 mov     eax,0140H
  470.                 sub     eax,ecx
  471.                 sub     edi,eax
  472.  
  473.                         ; Multiplica eax por 18
  474.                         ;mov     ecx,eax
  475.                         mov     ebp,eax
  476.                         shl     eax,4   ;*16
  477.                         ;shl     ecx,2   ;*4
  478.                         add     ebp,ebp ;*2
  479.                         ;add     eax,ecx
  480.                         add     eax,ebp
  481.  
  482.                 add     eax,OFFSET Unrolled1
  483.                 mov     esi,[_env_map_adr]
  484.                 add     edi,[_frame_buffer_adr]
  485.                 call    eax
  486.                 jmp     near ptr L33            ; Cerrar el bucle de scans
  487.  
  488.  
  489.  
  490. L28:            mov     bp,[long_side_u]
  491.                 mov     si,[long_side_v]
  492.  
  493.                 mov     ecx,[long_side_x]
  494.                 sar     ecx,16
  495.                 mov     ebx,[short_side_x]
  496.                 sar     ebx,16
  497.  
  498.                 cmp     cx,0
  499.                 jl      near ptr L33
  500.                 cmp     bx,MAX_X
  501.                 jg      near ptr L33
  502.  
  503.                 cmp     bx,0
  504.                 jge     short L29
  505.                 mov     bx,0
  506. L29:
  507.  
  508.                 cmp     cx,MAX_X
  509.                 jle     short L31
  510.                         movzx   edx,cx
  511.                         mov     ecx,MAX_X
  512.                         sub     edx,MAX_X
  513.                         sub     edi,edx
  514. L30:                    add     bp,[pixel_inc_u]
  515.                         add     si,[pixel_inc_v]
  516.                         dec     edx
  517.                         jne     short L30
  518. L31:
  519.  
  520.                 sub     cx,bx
  521.                 cmp     cx,0
  522.                 jge     short L32
  523.                 neg     cx
  524. L32:            inc     cx
  525.                 movzx   ecx,cx
  526.  
  527.                 cmp     [current_y],MIN_Y
  528.                 jl      near ptr L33
  529.                 cmp     [current_y],MAX_Y
  530.                 jg      near ptr L33
  531.  
  532.                 ; Carga los registros con los valores necesarios
  533.                 ; para el inner loop
  534.                 mov     ebx,esi
  535.                 shl     ebx,16
  536.                 mov     bx,bp
  537.                 mov     dx,[pixel_inc_v]
  538.                 shl     edx,16
  539.                 mov     dx,[pixel_inc_u]
  540.  
  541.                 mov     eax,0140H
  542.                 sub     eax,ecx
  543.                 add     edi,eax
  544.  
  545.                         ; Multiplica eax por 18
  546.                         ;mov     ecx,eax
  547.                         mov     ebp,eax
  548.                         shl     eax,4   ;*16
  549.                         ;shl     ecx,2   ;*4
  550.                         add     ebp,ebp ;*2
  551.                         ;add     eax,ecx
  552.                         add     eax,ebp
  553.  
  554.                 add     eax,OFFSET Unrolled2
  555.                 mov     esi,[_env_map_adr]
  556.                 add     edi,[_frame_buffer_adr]
  557.                 call    eax
  558. L33:
  559.                 ; Incrementa valores para el próximo scan
  560.                 mov     ax,[long_side_inc_u]
  561.                 add     [long_side_u],ax
  562.                 mov     ax,[long_side_inc_v]
  563.                 add     [long_side_v],ax
  564.                 mov     eax,[long_side_inc_x]
  565.                 add     [long_side_x],eax
  566.                 mov     eax,[short_side_inc_x]
  567.                 add     [short_side_x],eax
  568.                 add     [current_frame_buffer_pointer],0140H
  569.                 inc     [current_y]
  570.                 pop     cx
  571.                 dec     cx
  572.                 jne     near ptr L22            ; Loop!
  573.  
  574. L34:            popad
  575.                 ret
  576.  
  577. ; Second possibility - cuando el triángulo tiene y1 = y2 <= y3
  578.      
  579. L35:            mov     ax,[x2]
  580.                 cmp     ax,[x1]
  581.                 jge     short L36
  582.                 mov     eax,[_ex1]
  583.                 mov     ecx,[_ex2]
  584.                 mov     ebx,[_ey1]
  585.                 mov     edx,[_ey2]
  586.                 mov     [_ex2],eax
  587.                 mov     [_ex1],ecx
  588.                 mov     [_ey1],edx
  589.                 mov     [_ey2],ebx
  590.                 mov     eax,[u2v2]
  591.                 mov     ecx,[u1v1]
  592.                 mov     [u2v2],ecx
  593.                 mov     [u1v1],eax
  594. L36:            mov     ax,[_u1]
  595.                 mov     [long_side_u],ax
  596.                 mov     ax,[_v1]
  597.                 mov     [long_side_v],ax
  598.                 mov     eax,[_ey3]
  599.                 sub     eax,[_ey1]
  600.                 or      eax,eax
  601.                 jnz     @@DY31OK
  602.                 inc     eax
  603. @@DY31OK:
  604.                 mov     [dy31],eax
  605.  
  606.                 mov     ax,[_u3]
  607.                 sub     ax,[_u1]
  608.                 cwde    
  609.                 cdq     
  610.                 idiv    [dy31]
  611.                 mov     [long_side_inc_u],ax
  612.                 mov     ax,[_v3]
  613.                 sub     ax,[_v1]
  614.                 cwde    
  615.                 cdq     
  616.                 idiv    [dy31]
  617.                 mov     [long_side_inc_v],ax
  618.                 mov     eax,[_ex3]
  619.                 sub     eax,[_ex1]
  620.                 shl     eax,10H
  621.                 cdq     
  622.                 idiv    [dy31]
  623.                 mov     [long_side_inc_x],eax
  624.                 mov     eax,[_ex3]
  625.                 sub     eax,[_ex2]
  626.                 shl     eax,10H
  627.                 cdq     
  628.                 idiv    [dy31]
  629.                 mov     [short_side_inc_x],eax
  630.                 mov     eax,[_ex1]
  631.                 shl     eax,10H
  632.                 mov     [long_side_x],eax
  633.                 mov     eax,[_ex2]
  634.                 shl     eax,10H
  635.                 mov     [short_side_x],eax
  636.                 mov     ax,[y1]
  637.                 mov     [current_y],ax
  638.  
  639.                 ; Calcula pixel_inc_u y pixel_inc_v
  640.                 movzx   eax,[_u2]
  641.                 movzx   ebx,[_u1]
  642.                 sub     eax,ebx
  643.                 cdq
  644.                 movsx   ebx,[x2]
  645.                 movsx   ecx,[x1]
  646.                 sub     ebx,ecx
  647.                 or      ebx,ebx
  648.                 jne     short L37
  649.                 inc     ebx
  650. L37:            idiv    ebx
  651.                 mov     [pixel_inc_u],ax
  652.                 movzx   eax,[_v2]
  653.                 movzx   ebx,[_v1]
  654.                 sub     eax,ebx
  655.                 cdq
  656.                 movsx   ebx,[x2]
  657.                 movsx   ecx,[x1]
  658.                 sub     ebx,ecx
  659.                 or      ebx,ebx
  660.                 jne     short L38
  661.                 inc     ebx
  662. L38:            idiv    ebx
  663.                 mov     [pixel_inc_v],ax
  664.  
  665.                 ; Calcula el puntero al frame_buffer
  666.                 movsx   eax,[current_y]
  667.                 movzx   ebx,[_frame_buffer_scan_width]
  668.                 imul    ebx
  669.                 mov     [current_frame_buffer_pointer],eax
  670.  
  671.                 mov     cx,[y3]
  672.                 sub     cx,[y1]
  673.                 or      cx,cx
  674.                 jnz     L39
  675.                 inc     cx
  676.  
  677. ;══════════════════════════════════════════════════════════════════════
  678. ; Bucle principal, una vez por scan - y1 == y2
  679. ;══════════════════════════════════════════════════════════════════════
  680. L39:            push    cx
  681. IFDEF ONLY_EVEN
  682.                 ; Dibuja solo las pares
  683.                 mov     ax,[current_y]
  684.                 test    ax,1
  685.                 jnz     NEAR PTR L44
  686. ENDIF
  687.                 mov     edi,[current_frame_buffer_pointer]
  688.                 mov     eax,[long_side_x]
  689.                 sar     eax,10H
  690.                 add     edi,eax
  691.  
  692.                 mov     bp,[long_side_u]
  693.                 mov     si,[long_side_v]
  694.  
  695.                 mov     ecx,[short_side_x]
  696.                 sar     ecx,10H
  697.                 mov     ebx,[long_side_x]
  698.                 sar     ebx,10H
  699.  
  700.                 cmp     bx,MAX_X
  701.                 jg      near ptr L44
  702.                 cmp     cx,0
  703.                 jl      near ptr L44
  704.                 cmp     cx,MAX_X
  705.                 jle     short L40
  706.                 mov     cx,MAX_X
  707. L40:
  708.  
  709.                 cmp     bx,0
  710.                 jge     short L42
  711.                         xor     edx,edx
  712.                         sub     dx,bx
  713.                         xor     ebx,ebx
  714.                         add     edi,edx
  715. L41:                    add     bp,[pixel_inc_u]
  716.                         add     si,[pixel_inc_v]
  717.                         dec     dx
  718.                         jne     short L41
  719.  
  720.  
  721. L42:            sub     cx,bx
  722.                 cmp     cx,0
  723.                 jge     short L43
  724.                 neg     cx
  725. L43:
  726.                 inc     cx
  727.                 movzx   ecx,cx
  728.  
  729.                 cmp     [current_y],MIN_Y
  730.                 jl      near ptr L44
  731.                 cmp     [current_y],MAX_Y
  732.                 jg      near ptr L44
  733.  
  734.                 mov     ebx,esi
  735.                 shl     ebx,16
  736.                 mov     bx,bp
  737.                 mov     dx,[pixel_inc_v]
  738.                 shl     edx,16
  739.                 mov     dx,[pixel_inc_u]
  740.  
  741.                 mov     eax,0140H
  742.                 sub     eax,ecx
  743.                 sub     edi,eax
  744.  
  745.                         ; Multiplica eax por 18
  746.                         ;mov     ecx,eax
  747.                         mov     ebp,eax
  748.                         shl     eax,4
  749.                         ;shl     ecx,2
  750.                         add     ebp,ebp
  751.                         ;add     eax,ecx
  752.                         add     eax,ebp
  753.  
  754.                 add     eax,OFFSET Unrolled3
  755.                 mov     esi,[_env_map_adr]
  756.                 add     edi,[_frame_buffer_adr]
  757.                 call    eax
  758.  
  759. L44:            mov     ax,[long_side_inc_u]
  760.                 add     [long_side_u],ax
  761.                 mov     ax,[long_side_inc_v]
  762.                 add     [long_side_v],ax
  763.                 mov     eax,[long_side_inc_x]
  764.                 add     [long_side_x],eax
  765.                 mov     eax,[short_side_inc_x]
  766.                 add     [short_side_x],eax
  767.                 add     [current_frame_buffer_pointer],0140H
  768.                 inc     [current_y]
  769.                 pop     cx
  770.                 dec     cx
  771.                 jne     near ptr L39
  772.                 popad
  773.                 ret
  774.  
  775. ; Vamos a despistar un poco...
  776. DB 'Square root of negative number', 0
  777. DB 'Ray traced too long', 0
  778.  
  779. ALIGN 16
  780.  
  781.         Unrolled1:
  782.         Unrolled3:
  783.         ; UNROLLED LOOP
  784.         I = 0
  785.         REPT 320
  786.                 mov     eax,ebx
  787.                 shr     eax,16
  788.                 mov     al,bh
  789.                 add     ebx,edx
  790.                 mov     al,[esi+eax]
  791.                 ;mov     [edi+I],al
  792.                 db 88h, 87h
  793.                 dd I
  794.         I = I + 1
  795.         ENDM
  796.         ; END UNROLLED LOOP
  797.         retn
  798.  
  799. ALIGN 16
  800.  
  801.         Unrolled2:
  802.         ; UNROLLED LOOP
  803.         I = 0
  804.         REPT 320
  805.                 mov     eax,ebx
  806.                 shr     eax,16
  807.                 mov     al,bh
  808.                 add     ebx,edx
  809.                 mov     al,[esi+eax]
  810.                 ;mov     [edi+I],al
  811.                 db 88h, 87h
  812.                 dd I
  813.         I = I - 1
  814.         ENDM
  815.         ; END UNROLLED LOOP
  816.         retn
  817.  
  818.  
  819. COMMENT %
  820.         Es igual que el unrolled1, mirar arriba
  821.         Unrolled3:
  822.         ; UNROLLED LOOP
  823.         I = 0
  824.         REPT 320
  825.                 mov     eax,ebx
  826.                 shr     eax,16
  827.                 mov     al,bh
  828.                 mov     al,[esi+eax]
  829.                 ;mov     [edi+I],al
  830.                 db 88h, 87h
  831.                 dd I
  832.                 add     ebx,edx
  833.         I = I + 1
  834.         ENDM
  835.         ; END UNROLLED LOOP
  836.         retn
  837. %
  838.         ENDP
  839.  
  840. _TEXT   ENDS
  841.  
  842.         END
  843.